package org.kia.manager;

import java.util.List;

import org.kia.activity.SearchActivity;
import org.kia.activity.interfaces.SearchActivityInterface;
import org.kia.activity.interfaces.SearchCategoriesInterface;
import org.kia.activity.interfaces.SearchItemsInterface;
import org.kia.data.Mocker;
import org.kia.data.adapters.RequestAdapter;
import org.kia.data.interfaces.OnDataReceivedListener;
import org.kia.data.model.CategoryModel;
import org.kia.data.model.ItemModel;

import android.util.Log;

/**
 * Controls over {@link SearchActivity}
 *  
 * @author Amir Lazarovich
 */
public class SearchManager extends KiaManager<SearchActivityInterface> {

	// ////////////////////////////////////////////
	// Constants
	// ////////////////////////////////////////////

	private static final String TAG = "SearchManager";
	
	// ////////////////////////////////////////////
	// Members
	// ////////////////////////////////////////////
	private static SearchManager sInstance;
	private SearchCategoriesInterface mCategoriesActivity;
	private SearchItemsInterface mItemsActivity;
	private List<CategoryModel> mCategories;
	private List<ItemModel> mItems;
	
	
	// ////////////////////////////////////////////
	// Constructors & Singleton related methods
	// ////////////////////////////////////////////

	/**
	 * Private constructor to prohibit more instances of this class
	 */
	private SearchManager() {

	}

	/**
	 * Get the (only) instance of this class
	 * 
	 * @return
	 */
	public synchronized static SearchManager getInstance() {
		if (sInstance == null) {
			sInstance = new SearchManager();
		}

		return sInstance;
	}

	// ////////////////////////////////////////////
	// Public
	// ////////////////////////////////////////////

	/**
	 * Fired when the Categories activity (fragment) is ready
	 * 
	 * @param context
	 */
	public void onCategoriesReady(SearchCategoriesInterface context) {
		mCategoriesActivity = context;
		if (mCategories != null) {
			// Found categories in cache - notify our activity
			mCategoriesActivity.setCategories(mCategories);
			// Clear cache
			mCategories = null;
		}
	}
	
	/**
	 * Fired when the Items in Category activity (fragment) is ready
	 * 
	 * @param context
	 */
	public void onItemsReady(SearchItemsInterface context, String categoryId) {
		mItemsActivity = context;
		loadItemsInCategoryData(categoryId);
	}
	
	/**
	 * 
	 */
	public void onCategoryDistroyed() {
		mCategoriesActivity = null;
	}

	/**
	 * 
	 */
	public void onItemsDistroyed() {
		mItemsActivity = null;
	}
	
	// ////////////////////////////////////////////
	// Private
	// ////////////////////////////////////////////

	/**
	 * Handle categories received from the server / mocker
	 * 
	 * @param data
	 */
	void onCategoriesReceived(List<CategoryModel> data) {
		if (mCategoriesActivity != null) {
			mCategoriesActivity.setCategories(data);
		} else {
			// Cache categories for later use (when our activity is ready)
			mCategories = data;
		}
	}
	
	void onItemsInCategoryReceived(List<ItemModel> data) {
		if (mItemsActivity != null) {
			mItemsActivity.setItems(data);
		} else {
			// Cache items for later use (when our activity is ready)
			mItems = data;
		}
	}
	
	/**
	 * Load data from the server and inform the activity when data arrives
	 */
	private void loadData() {
		if (SettingsManager.getInstance().isMocking(mActivity.getContext())) {
			Log.i(TAG, "loadData:: mocking data");
			// Mocking data from the server
			onCategoriesReceived(Mocker.getCategories());
			//mActivity.setAutoCompleteData(Mocker.getAutoCompleteData());
			return;
		}
		
		// ServerComManager.getInstance().getAutoCompleteData(this);
		ServerComManager.getInstance().getCategories(mActivity.getContext(),
				new OnDataReceivedListener<List<CategoryModel>>() {

					@Override
					public void onDataReceived(List<CategoryModel> data) {
						onCategoriesReceived(data);
					}

					@Override
					public void onDataFailure(RequestAdapter request, long errorCode, String errorMessage) {
						Log.e(TAG, "Couldn't get categories from the server");
					}

				});
	}
	
	/**
	 * Load data from the server and inform the activity when data arrives
	 */
	private void loadItemsInCategoryData(String categoryId) {
		if (true || SettingsManager.getInstance().isMocking(mActivity.getContext())) {
			Log.i(TAG, "loadData:: mocking data");
			// Mocking data from the server
			onItemsInCategoryReceived(Mocker.getItemsInCategory());
			//mActivity.setAutoCompleteData(Mocker.getAutoCompleteData());
			return;
		}
		
		// ServerComManager.getInstance().getAutoCompleteData(this);
		ServerComManager.getInstance().getItemsInCategory(mActivity.getContext(), categoryId,
				new OnDataReceivedListener<List<ItemModel>>() {

					@Override
					public void onDataReceived(List<ItemModel> data) {
						onItemsInCategoryReceived(data);
					}

					@Override
					public void onDataFailure(RequestAdapter request, long errorCode, String errorMessage) {
						Log.e(TAG, "Couldn't get categories from the server");
					}

				});
	}

	// ////////////////////////////////////////////
	// Overrides
	// ////////////////////////////////////////////

	@Override
	protected void onActivityReady() {
		loadData();
	}
	
}
